package com.cn.por.config.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.UrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.security.SpringSessionBackedSessionRegistry;

import com.cn.por.biz.user.service.impl.ProUserDetailsServiceImpl;
/**
 * 开启基于方法的权限控制 @EnableGlobalMethodSecurity
 * @author wen
 *
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true,jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter{
	
//	@SuppressWarnings("rawtypes")
//	@Autowired
//	FindByIndexNameSessionRepository sessionRepository;
	@Autowired
	ProUserDetailsServiceImpl proUserDetails;
	
	@Autowired
	CustomSecurityMetaDataSource metaDateSource;
	
	@Autowired
	AjaxAuthenticationEntryPoint ajaxAuthenticationEntryPoint;

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		/**
		 
		auth.inMemoryAuthentication()
				.withUser("admin")
				.password("{noop}123")
				.roles("admin");**/
		auth.userDetailsService(proUserDetails)
			.passwordEncoder(passwordEndcoder());
	}
	
	@Bean
	public BCryptPasswordEncoder passwordEndcoder() {
		return new BCryptPasswordEncoder();
	}
	
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
//		http.authorizeRequests()
//        .anyRequest().authenticated()
//        .and()
//        .formLogin()
//        .and()
//        .csrf()
//        .disable()
//        .sessionManagement()
//        .maximumSessions(1)
//        .sessionRegistry(sessionRegistry());
		ApplicationContext applicationContext = http.getSharedObject(ApplicationContext.class);
		http.apply(new UrlAuthorizationConfigurer<>(applicationContext))
				.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
					@Override
					public <O extends FilterSecurityInterceptor> O postProcess(O object) {
						object.setSecurityMetadataSource(metaDateSource);
						return object;
					}
				});
		http.authorizeRequests().anyRequest().authenticated()
//		.and().formLogin()
//			  .successHandler(new PorAuthenticationSuccessHandler())
//			  .failureHandler(new PorAuthenticationFailureHandler())
		      .and()
		      .csrf()
		      .disable()
//		      .sessionManagement()
		      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)//配置取消session功能
//		      .maximumSessions(1)    //配置取消session功能
//		      .sessionRegistry(sessionRegistry()) //配置取消session功能
		      .and().addFilterAfter(new JWTAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class)
		      .addFilterAt(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
		      //登陆异常处理
		      .exceptionHandling().authenticationEntryPoint(ajaxAuthenticationEntryPoint)
		      ; 
		//http.addFilterAt();
	}
	
//	@SuppressWarnings({ "rawtypes", "unchecked" })
//	@Bean
//    SpringSessionBackedSessionRegistry sessionRegistry() {
//        return new SpringSessionBackedSessionRegistry(sessionRepository);
//    }

	@Bean	
	CustomAuthenticationFilter customAuthenticationFilter() throws Exception {	
	    CustomAuthenticationFilter filter = new CustomAuthenticationFilter();	
	    filter.setAuthenticationSuccessHandler(new PorAuthenticationSuccessHandler());	
	    filter.setAuthenticationFailureHandler(new PorAuthenticationFailureHandler());	
	    filter.setAuthenticationManager(super.authenticationManagerBean());	
	    return filter;	
	}
}
